﻿/*+===================================================================
File:      BossTwo.cpp

Summary:   Định nghĩa các phương thức của CBossTwo.
===================================================================+*/

#include "BossTwo.h"
#include "PlayState.h"

static float MOUTH_BULLETS_ANGLE[3] = { -120.0f, -90.0f, -60.0f };

CBossTwo::CBossTwo(CBill* bill, D3DXVECTOR2 pos, int id, int typeId) : CMoveableObject(pos, id, typeId)
{
	m_pGun = new CGun(ID_BOSS_TWO_BULLET, 3, 1);
	m_bill = bill;

	m_leftHand = new CBossTwoHand(bill, D3DXVECTOR2(425.0f, 4174.0f), 0, ID_BOSS_TWO_LEFT_HAND);
	m_rightHand = new CBossTwoHand(bill, D3DXVECTOR2(214.0f, 4174.0f), 0, ID_BOSS_TWO_RIGHT_HAND);

	m_nLife = 30;
	m_bIsAppear = false;
	m_pExplosionGroup = new CExplosionGroup(m_pos, id, ID_BIG_EXPLOSION, 0.68f, ID_BIG_EXPLOSION);
	m_fTimeDie = 2.0f;

	m_nStatus = STATUS_BOSS2_NONE;

	m_pSprite = m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_HIDE);
	m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_MOUTH_CLOSING);
	m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_MOUTH_OPENING);
	m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_MOUTH_OPENED);
	m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_APPEAR);
	m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_DIE);
}


CBossTwo::~CBossTwo()
{
	if (m_pExplosionGroup)
		delete m_pExplosionGroup;
	if (m_pGun)
		delete m_pGun;
	if (m_leftHand)
		delete m_leftHand;
	if (m_rightHand)
		delete m_rightHand;
	if (m_bill)
		delete m_bill;
}

void CBossTwo::Update(float timeFrame)
{
	if (!m_bIsLive)
	{
		if (m_fTimeDie > 0)
		{
			m_fTimeDie -= timeFrame;
			this->Explode(timeFrame);
		}
		else if (m_fTimeDie < 0)
		{
			m_fTimeDie = 0.0f;
		}
	}
	if (m_bIsAppear)
	{
		if (m_timeChange > 0.0f)
		{
			m_timeChange -= timeFrame;

			if (m_nStatus == STATUS_MOUTH_OPENED)
			{
				if (m_timeFire > 0.0f)
				{
					m_timeFire -= timeFrame;
				}
				else
				{
					m_timeFire = 4.0f;
					Fire();
				}
			}
		}
		else
		{
			switch (m_nStatus)
			{
			case STATUS_BOSS2_NONE:
				m_timeChange = 1.0f;
				m_nStatus = STATUS_BOSS2_APPEARING;
				break;
			case STATUS_BOSS2_START:
				m_timeChange = 1.0f;
				m_nStatus = STATUS_BOSS2_APPEARING;
				break;
			case STATUS_BOSS2_APPEARING:
				m_timeChange = 8.0f;
				m_nStatus = STATUS_MOUTH_CLOSE;
				break;
			case STATUS_MOUTH_CLOSE:
				m_timeChange = 0.1f;
				m_nStatus = STATUS_MOUTH_OPENING;
				break;
			case STATUS_MOUTH_OPENING:
				m_timeChange = 3.0f;
				m_timeFire = 1.0f;
				m_nStatus = STATUS_MOUTH_OPENED;
				break;
			case STATUS_MOUTH_OPENED:
				m_timeChange = 0.1f;
				m_nStatus = STATUS_MOUTH_CLOSING;
				break;
			case STATUS_MOUTH_CLOSING:
				m_timeChange = 4.0f;
				m_nStatus = STATUS_MOUTH_CLOSE;
				break;

			}
		}

		if (m_nStatus != STATUS_BOSS2_NONE && m_nStatus != STATUS_BOSS2_START && m_nStatus != STATUS_BOSS2_APPEARING)
		{
			m_leftHand->Update(timeFrame);
			m_rightHand->Update(timeFrame);
		}

		UpdateAnimation();
		m_pSprite->Update(timeFrame);
		UpdateBox(timeFrame);
	}
}

void CBossTwo::UpdateAnimation()
{
	switch (m_nStatus)
	{
	case STATUS_BOSS2_NONE:
		m_pSprite = m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_HIDE);
		break;
	case STATUS_BOSS2_START:
		m_pSprite = m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_HIDE);
		break;
	case STATUS_BOSS2_APPEARING:
		m_pSprite = m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_APPEAR);
		break;
	case STATUS_MOUTH_CLOSE:
		m_pSprite = m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_MOUTH_CLOSING);
		break;
	case STATUS_MOUTH_OPENING:
	case STATUS_MOUTH_CLOSING:
		m_pSprite = m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_MOUTH_OPENING);
		break;
	case STATUS_MOUTH_OPENED:
		m_pSprite = m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_MOUTH_OPENED);
		break;
	case STATUS_BOSS2_DIE:
		m_pSprite = m_pResourceManager->GetSprite(ID_SPRITE_BOSS_TWO_DIE);
		break;
	}
}

void CBossTwo::UpdateBox(float timeFrame)
{
	m_box.width = 50.0f;
	m_box.height = 80.0f;
	m_box.x = m_pos.x - m_pSprite->GetWidth() / 2.0f + 230.0f;
	m_box.y = m_pos.y + m_pSprite->GetHeight() / 2.0f - 70.0f;
}

void CBossTwo::UpdateCollision(vector<CGameObject*> vecGameObjs, float timeFrame)
{
	if (!m_bIsAppear)
		return;


	if (m_nStatus != STATUS_BOSS2_NONE && m_nStatus != STATUS_BOSS2_START && m_nStatus != STATUS_BOSS2_APPEARING)
	{
		m_leftHand->UpdateCollision(vecGameObjs, timeFrame);
		m_rightHand->UpdateCollision(vecGameObjs, timeFrame);
	}


	if (m_nStatus == STATUS_MOUTH_CLOSE || m_nStatus == STATUS_BOSS2_DIE)
		return;

	float timeCollision = timeFrame;
	CGameObject* objCollision = NULL; // Đối tượng va chạm sớm nhất.
	float normalx = 0.0f, normaly = 0.0f;

	// Xử lí va chạm với đạn của Bill
	for (int i = 0; i < CPlayState::s_billBullets.size(); i++)
	{
		if (CPlayState::s_billBullets[i]->IsLive())
		{
			float t = CheckCollision(CPlayState::s_billBullets[i], normalx, normaly, timeFrame);

			if (t < timeFrame && t < timeCollision)
			{
				// Tìm đối tượng và thời gian va chạm sớm nhất.
				timeCollision = t;
				objCollision = CPlayState::s_billBullets[i];
			}
		}
	}

	// Xử lí va chạm
	if (objCollision != NULL)
	{
		this->Kill();
		objCollision->Kill();
	}
}

void CBossTwo::Draw()
{
	if (!m_bIsAppear)
		return;

	D3DXVECTOR2 pos;
	pos = CViewport::GetInstance()->TransformMatrix(m_pos);
	m_pSprite->Draw(pos);

	if (m_nStatus != STATUS_BOSS2_NONE && m_nStatus != STATUS_BOSS2_START && m_nStatus != STATUS_BOSS2_APPEARING)
	{
		m_leftHand->Draw();
		m_rightHand->Draw();
	}
}

bool CBossTwo::Kill()
{
	if (m_nLife > 1)
		m_nLife--;
	else
	{
		m_bIsLive = false;
		m_nStatus = STATUS_BOSS2_DIE;
		D3DXVECTOR2 exPos;
		exPos.x = m_pos.x;
		exPos.y = m_pos.y + m_pSprite->GetHeight() / 2.0f - 96.0f;
		CExplosion* explosion = new CExplosion(exPos, 0, ID_SMALL_EXPLOSION);
		CPlayState::s_objsOutSideQuadTree.push_back(explosion);

		m_leftHand->Kill();
		m_rightHand->Kill();
	}

	return true;
}

void CBossTwo::Explode(float timeFrame)
{
	if (m_aPosEx.size() <= 14)
	{
		m_aPosEx.push_back(D3DXVECTOR2(232, 4290));
		m_aPosEx.push_back(D3DXVECTOR2(276, 4290));
		m_aPosEx.push_back(D3DXVECTOR2(276, 4235));
		m_aPosEx.push_back(D3DXVECTOR2(276, 4180));
		m_aPosEx.push_back(D3DXVECTOR2(276, 4125));
		m_aPosEx.push_back(D3DXVECTOR2(276, 4070));
		m_aPosEx.push_back(D3DXVECTOR2(276, 4015));
		m_aPosEx.push_back(D3DXVECTOR2(364, 4290));
		m_aPosEx.push_back(D3DXVECTOR2(364, 4235));
		m_aPosEx.push_back(D3DXVECTOR2(364, 4180));
		m_aPosEx.push_back(D3DXVECTOR2(364, 4125));
		m_aPosEx.push_back(D3DXVECTOR2(364, 4070));
		m_aPosEx.push_back(D3DXVECTOR2(364, 4015));
		m_aPosEx.push_back(D3DXVECTOR2(408, 4290));
		m_pExplosionGroup->SetArrayPos(m_aPosEx);
	}
	m_pExplosionGroup->Update(timeFrame);
}

void CBossTwo::Fire()
{
	D3DXVECTOR2 bulletPos;
	bulletPos.x = m_box.x + m_box.width / 2.0f;
	bulletPos.y = m_box.y - m_box.height / 2.0f;

	for (int i = 0; i < 3; i++)
	{
		m_pGun->SetBulletAngle(MOUTH_BULLETS_ANGLE[i]);
		m_pGun->Fire(bulletPos);
	}
}

CBossTwoPartArm* CBossTwo::GetLeftHeadArm()
{
	return m_leftHand->GetHeadArm();
}

CBossTwoPartArm* CBossTwo::GetRightHeadArm()
{
	return m_rightHand->GetHeadArm();
}